package com.aaa.auth.config;

import com.aaa.auth.service.MyUserService;
import com.aaa.common.util.JWTUtil;
import com.aaa.common.vo.Result;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Autowired
    private MyUserService userService;


    //重写父类的两个方法
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //设置登录表单的规则
        http.formLogin()
                //如果登录成功执行的函数
                .successHandler(successHandler())
                //登陆失败执行的函数
                .failureHandler(failureHandler())
                //放行
                .permitAll();
        //设置security允许登录跨域
        http.cors();
        //关闭跨域伪造请求
        http.csrf().disable();
        //其他所以的请求都需要认证
        http.authorizeRequests().anyRequest().authenticated();
    }
    //登录成功
    private AuthenticationSuccessHandler successHandler(){
        return (request, response, authentication) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            //生产token---userid+permission---JWT.
            //获取登录成功后用户的对象
            User user = (User) authentication.getPrincipal();
            //登录成功的账号
            String username = user.getUsername();
            //获取登录成功的账号具有的权限
            Collection<GrantedAuthority> authorities = user.getAuthorities();
            List<String> permissions = authorities.stream()
                    .filter(item->item.getAuthority()!=null)
                    .map(item->item.getAuthority()).collect(Collectors.toList());
            Map<String, Object> map = new HashMap<>();
            map.put("username",username);
            map.put("permissions",permissions);
            //按照账号和权限生产token
            String token = JWTUtil.createJWT(map);

            //封装到响应对象中
            Result result = new Result(2000, "登录成功", token);
            String jsonString = JSON.toJSONString(result);
            writer.print(jsonString);

            writer.flush();
            writer.close();
        };
    }

    //登陆失败执行的方法
    private AuthenticationFailureHandler failureHandler(){
        return (request,response, e) ->{
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();

            Result result = new Result(5000,"账号或者密码错误");
            String jsonString = JSON.toJSONString(result);
            writer.print(jsonString);
            writer.flush();
            writer.close();
        };
    }
}

